package com.redxiii.spike.pmi.command;

import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.SortedSet;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.redxiii.spike.api.command.CommandFactory;
import com.redxiii.spike.api.command.InitializationRequired;
import com.redxiii.spike.api.message.ImMessage;
import com.redxiii.spike.api.pmi.entity.Issue;
import com.redxiii.spike.api.pmi.entity.Member;
import com.redxiii.spike.pmi.HandlerSession;
import com.redxiii.spike.pmi.commons.PmiDatabase;
import com.redxiii.spike.pmi.commons.UserSettings;
import com.redxiii.spike.util.command.InternetCommand;
import com.redxiii.spike.util.message.BasicMsgInterpreter;

/**
 * @author Daniel Filgueiras
 * 04/05/2011
 */
@InitializationRequired
@CommandFactory(BasicMsgInterpreter.class)
public class ShowIssues extends InternetCommand {

	private static final Logger logger = LoggerFactory.getLogger(ShowIssues.class);

	protected PmiDatabase database;
	protected String userId;
	protected String matchText;
	
	@Override
	public boolean proccess(ImMessage message) {
		
		database = HandlerSession.getDatabase();
		if (database == null)
			return false;
		
		StringBuilder buffer = new StringBuilder();
		
		Member member = null;
		if (userId == null) {
			userId = remoteId;
			member = database.getMemberByMail(userId);
		} else {
			member = database.getMemberByLogin(userId);
		}
		
		if (member == null) {
			service.reply(message,"Unknown member: " + userId);
			return true;
		}
		
		UserSettings userSettings = HandlerSession.getUserSettings(remoteId);
		Set<Long> issuesList = new LinkedHashSet<Long>();
		userSettings.setIssuesList(issuesList);
		
		SortedSet<Issue> issues = fetchIssues(member.getId());
		
		if (issues == null) {
			buffer.append("Fail loading issues...");
		} else if (issues.size() == 0) {
			buffer.append("No issues found...");
		} else {
			logger.debug("Match description: {}", matchText);
			
			buffer.append(issues.size()).append(" issues from ").append(member.getName()).append("\r\n");
			for (Issue issue : issues) {
				issuesList.add(issue.getId());
				
				buildResponse(issue, buffer);
			}
		}
		
		service.reply(message, buffer);

		return true;
	}
	
	protected void buildResponse(Issue issue, StringBuilder buffer) {
		buffer
			.append("#")
			.append(Long.toString(issue.getId()))
			.append(" - ")
			.append(issue.getProject() != null ? issue.getProject().getName() : "?")
			.append(" - ")
			.append(issue.getSummary())
			.append("\r\n");
	}
	
	protected SortedSet<Issue> fetchIssues(String memberId) {
		return filterIssues(database.getMyIssues(memberId));
	}
	
	protected SortedSet<Issue> filterIssues(SortedSet<Issue> issues) {
		Iterator<Issue> iterator = issues.iterator();
		while (iterator.hasNext()) {
			Issue issue = iterator.next();
			
			if (matchText != null && !issue.getSummary().toLowerCase().contains(matchText.toLowerCase())) {
				logger.debug("Issue id {} discarted", issue.getId());
				iterator.remove();
			}
		}
		return issues;
	}
}
